/**
 * 
 */
package com.ftpserver;

import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.time.Duration;
import java.time.LocalDateTime;

import org.apache.ftpserver.usermanager.impl.BaseUser;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.file.FileAppender;
import cn.hutool.core.net.NetUtil;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil;
import cn.hutool.cron.task.Task;
import cn.hutool.extra.ftp.SimpleFtpServer;
import cn.hutool.setting.Setting;

/**
 * @author w.weizhen
 *  
 */
public class ServerDoor {
    private static final String user_dir = System.getProperty("user.dir")+File.separator;
    //读取classpath下的config.setting,不使用变量
    private static final Setting setting = new Setting(user_dir+"config.setting", CharsetUtil.CHARSET_UTF_8, true);
    private static final String name = setting.getStr("name");//设定的用户名
    private static final String password = setting.getStr("password");//设定的用户秘密
    private static final String dir = setting.getStr("dir");//设定的文件夹路径
    private static final Integer port = setting.getInt("port")!=null&&NetUtil.isValidPort(setting.getInt("port"))?setting.getInt("port"):21;//设定的端口号
    private static final Boolean log = setting.getBool("log");//是否开启日志
    private static final Integer expire_logs_days = setting.getInt("expire_logs_days");//日志保存天数
    /**
     * 程序入口
     */
    public static void main(String[] args) {
        log("程序启动中!");
        try {
            //首先去校验配置文件中的必须参数,如果参数缺失则不能启动应用。
            //只在启动的时候校验一次,
            if(!verifyConfig())
            {
                log("配置文件没有通过校验!程序未启动!");
                return;
            }
            //开启ftp服务
            BaseUser user = new BaseUser();
            user.setName(name);
            user.setPassword(password);
            user.setHomeDirectory(dir);
            SimpleFtpServer.create().setPort(port).addUser(user).start();
            //过期日志管理,每天凌晨2:00清除过期日志文件
            CronUtil.schedule("0 0 2 * * ?", new Task() {
                @Override
                public void execute() {
                    expireLog();
                }
            });
            // 支持秒级别定时任务
            CronUtil.setMatchSecond(true);
            CronUtil.start();
        } catch (Exception e) {
        	StringWriter sw = new StringWriter();
		    e.printStackTrace(new PrintWriter(sw,true));
		    log(sw.toString());
        }
        log("程序已启动!");
    }
    
    // 校验参数是否全部在配置文件中
    private static boolean verifyConfig()
    {
        boolean verify = true;
        try {
            // 用户名为空
            if(StrUtil.isBlank(name))
            {
                log("配置文件config.settig中name[用户名]没有配置!");
                verify = false;
            }
            // 密码为空
            if(StrUtil.isBlank(password))
            {
                log("配置文件config.settig中password[密码]没有配置!");
                verify = false;
            }
            // 路径为空
            if(StrUtil.isBlank(dir))
            {
                log("配置文件config.settig中dir[路径]没有配置!");
                verify = false;
            }
            else
            {
                //路径是否存在
                File file = new File(dir);
                if(!file.exists()||!file.isDirectory())
                {
                    log("配置文件config.settig中dir[路径]不存在或不是一个文件夹!");
                    verify = false;
                }
            }
            //配置端口是否可用
            if(!NetUtil.isUsableLocalPort(port))
            {
                log("配置文件config.settig中port[端口]:"+port+"不可用!");
                verify = false;
            }
        } catch (Exception e) {
            verify = false;
            StringWriter sw = new StringWriter();
		    e.printStackTrace(new PrintWriter(sw,true));
		    log(sw.toString());
        }
        return verify;
    }
    
    // 写日志,这里不用组件,自己写一个简单的
    private static void log(String content)
    {
        //日志是否开启
        if (!log) {return;}
        //当前时间
        String now = DateUtil.now();
        //日志文件路径
        String path = user_dir+"log"+File.separator+DateUtil.today()+".log";
        //写入文件
        File file = new File(path);
        FileAppender appender = new FileAppender(file, 10, true);
        appender.append(now + "  " + content);
        appender.flush();
    }
    
    // 管理过期日志
    private static void expireLog()
    {
        log("开始管理过期日志!");
        //日志文件路径
        File directory = new File(user_dir+"log");
        if(!directory.exists())
        {
            log("结束管理过期日志!日志目录不存在!");
            return;
        }
        File[] files = directory.listFiles();
        if (files==null||files.length<1) 
        {
            log("结束管理过期日志!没有日志文件!");
            return;
        }
        //当前时间
        String now = DateUtil.today();
        LocalDateTime end = LocalDateTimeUtil.parse(now, DatePattern.NORM_DATE_PATTERN);
        for (File file : files) 
        {
        	String name = file.getName();
            LocalDateTime start = LocalDateTimeUtil.parse(name.replaceAll(".log", ""), DatePattern.NORM_DATE_PATTERN);
            Duration between = LocalDateTimeUtil.between(start, end);
            if(between.toDays() >= expire_logs_days)
            {
                file.delete();
            }
        }
        log("结束管理过期日志!");
    }
    
}